*Format columns of matrix output to look more like estout/estab

capture program drop format_col

program define format_col

syntax varlist, [delimiters(str)] [stars]

local obs=_N

if "`delimiters'"!="" {
	local prefix=substr("`delimiters'",1,1)
	local suffix=substr("`delimiters'",2,1)
	}
	
foreach var of varlist `varlist' {
	capture tostring `var', force replace
	replace `var'="" if subinstr(`var'," ","",.)=="."
	if "`delimiters'"!="" {
		foreach i of num 1(2)`obs' {
			local j = `i'+1
			local coef=real(`var') in `i'
			local se=real(`var') in `j'
			if "`stars'"!="" {
				local pvalue=2*(1-normal(abs(`coef'/`se')))
				if `pvalue'<.01 local star ***
				else if `pvalue'<.05 local star **
				else if `pvalue'<.1 local star *
				else local star
				}
			autoformat `coef'
			local coef_fmt: di $format `coef'
			local coef_fmt=subinstr("`coef_fmt'"," ","",.)
			if "`coef_fmt'"=="-0.000" local coef_fmt="0.000"
			qui replace `var'="`coef_fmt'`star'" in `i'
			autoformat `se'
			local se_fmt: di $format `se'
			local se_fmt=subinstr("`se_fmt'"," ","",.)
			qui replace `var'="`prefix'`se_fmt'`suffix'" in `j'
			}
		}
	else {
		foreach i of num 1(1)`obs' {
			local val=real(`var') in `i'
			autoformat `val'
			local val_fmt: di $format `val'
			if "`val'"!="." qui replace `var'="`val_fmt'" in `i'
			qui replace `var'=strtrim(`var')
			}
		}
	}
	
end

*Format CSV files generated by estout/esttab

capture program drop format_csv

program define format_csv
syntax using, [spacers(str)] [h_space(str)] [allquote n_space]

preserve
import delimited `using', varnames(1) clear stringcols(_all)
unab varlist: _all
local v1: word 1 of `varlist'
rename `v1' outcome
qui gen sno=_n

if "`n_space'"=="" { 
	local oldN=_N
	local newN=`oldN'
	local counter=`oldN'-1
	foreach i of num 1/`counter' {
		local j=`i'+1
		local space1=outcome in `i'
		local space2=outcome in `j'
		if (`"`space1'"'!=`""' & (`"`space2'"'==`""'|`"`space2'"'==`"="""')) ///
			| `"`space2'"'==`"="r2""' {
			local newN=`newN'+1
			qui set obs `newN'
			qui replace sno=`j'+.5 in `newN'
			}
		}
	}

if "`h_space'"!="" { 
	local spaces: word count `h_space'
	local oldN=_N
	local newN=`oldN'+`spaces'
	qui set obs `newN'
	qui replace sno=_n if _n>`oldN'
	local space_counter=1
	foreach space in `h_space' {
		if `space_counter'!=1 {
			local prev_space_counter=`space_counter'-1
			local prev_space: word `prev_space_counter' of `h_space'
			if `prev_space'==`space' {
				local increment=`increment'+.1
				}
			else local increment=.1
			}
		else local increment=.1
		local sno_counter=`oldN'+`space_counter'
		qui replace sno=`space'+`increment' in `sno_counter'
		local space_counter=`space_counter'+1
		}
	}

sort sno
drop sno


unab varlist: _all
local columns: word count `varlist'

if "`spacers'"!="" {
	local j 1
	local spacer: word `j' of `spacers'
	local newvarlist outcome
	foreach i of num 2/`columns' {
		local k=`i'-1
		local var: word `i' of `varlist'
		if "`spacer'"=="`k'" {
			gen spacer`k'=""
			local newvarlist `newvarlist' `var' spacer`k'
			local ++j
			local spacer: word `j' of `spacers'
			}
		else local newvarlist `newvarlist' `var'
		}
	order `newvarlist'
	}


if "`allquote'"!="" {
	foreach var of varlist _all {
		qui replace `var'=`"=""'+`var'+`"""' 
		}
	}
else {
	foreach var of varlist _all {
		qui replace `var'=`"="""' if `var'==""
		}
	}
	
export delimited `using', replace
restore
end

*Automatically format numbers for string output
capture program drop autoformat
program define autoformat

if int(`1')==`1' global format "%12.0f"
else if abs(`1')>10 global format "%9.1f"
else if abs(`1')>1 global format "%9.2f"
else if abs(`1')>.1 global format "%9.3f"
else if abs(`1')>.01 global format "%9.4f"
else if abs(`1')>.001 global format "%9.5f"
else if abs(`1')>.0001 global format "%9.6f"
else if abs(`1')<.0001 global format "%9.3f"

*special format for number 1 (in this case it's always a standard error)
if int(`1')==1 global format "%9.3f"

end
